package com.pe.pgn.clubpgn.dao.impl;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.pe.pgn.clubpgn.common.CLPConstantes;
import com.pe.pgn.clubpgn.dao.IncidenciaPuntosDao;
import com.pe.pgn.clubpgn.dao.hibernate.GenericDaoHibernate;
import com.pe.pgn.clubpgn.domain.ClpbClientePersona;
import com.pe.pgn.clubpgn.domain.ClpbTipoIncidenciaPuntos;
import com.pe.pgn.clubpgn.domain.ClpmIncidenciaPuntos;
import com.pe.pgn.clubpgn.domain.beans.BNClientesPersona;
import com.pe.pgn.clubpgn.domain.beans.BNIncidenciaPuntos;
import com.pe.pgn.clubpgn.webapp.util.CalendarUtil;

@Repository("incidenciaPuntosDao")
public class IncidenciaPuntosDaoImpl extends GenericDaoHibernate<ClpmIncidenciaPuntos, Long> implements IncidenciaPuntosDao{

	
	private JdbcTemplate jdbcTemplate;
	
	@Autowired
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}
	
	public IncidenciaPuntosDaoImpl() {
		super(ClpmIncidenciaPuntos.class);
	}

	@SuppressWarnings("unchecked")
	public List<BNIncidenciaPuntos> busquedaIncidencia(String daClientePersona,
			String codeTarjeta, String daInicioDoc, String daFinDoc,
			String coTipoIncidenciaPuntos,Long coTipo) {

		StringBuffer query = new StringBuffer();
		query.append(" SELECT clpmid.id                                                  AS id                    , ");
		query.append("   clpmid.co_codigo_tarjeta_persona                                 AS coTarjetaPersona      ,");
		query.append("   clpmid.co_cliente_persona                                        AS coClientePersona      ,");
		query.append(" 		  clpmid.co_tipo                                 AS coTipo,");
		query.append(" 		  clpmid.co_tipo_incidencia_puntos                                 AS coTipoIncidenciaPuntos,");
		query.append(" 		  clpbti.de_tipo_incidencia_puntos AS daTipoIncidenciaPuntos, ");
		query.append(" 		   to_char(clpmid.da_fecha_incidencia,'"+CLPConstantes.DATE_PATTERN+"')  AS daFechaIncidencia     ,");
		query.append(" 		  clpmid.de_sustentacion                                             AS deSustentacion        ,");
		query.append(" 		  clpmid.va_puntos                                                 AS vaPuntos              ,");
		query.append(" 		   clpbcp.de_nombre||' '|| clpbcp.de_ape_paterno||' '||clpbcp.de_ape_materno AS deClientePersona");
		query.append(" 		   FROM clpm_incidencia_puntos clpmid ");
		query.append(" 		JOIN clpb_tipo_incidencia_puntos clpbti ");
		query.append(" 		     ON clpbti.id = clpmid.co_tipo_incidencia_puntos ");
		query.append(" 		JOIN clpb_cliente_persona clpbcp ");
		query.append(" 		     ON clpbcp.id = clpmid.co_cliente_persona ");
		query.append(" 		     WHERE 1= 1 ");
		
			if (StringUtils.isNotBlank(daClientePersona))
			query.append(" and upper(clpbcp.de_nombre||' '|| clpbcp.de_ape_paterno||' '||clpbcp.de_ape_materno) like upper('%"+daClientePersona.trim()+"%') ");

					
			if (StringUtils.isNotBlank(codeTarjeta))
			query.append(" and clpmid.co_codigo_tarjeta_persona like ").append("'%"+codeTarjeta+"%'");
			
			
			
			if (StringUtils.isNotBlank(daInicioDoc) && StringUtils.isNotBlank(daFinDoc)){
				query.append(" and (clpmid.da_fecha_incidencia  >= to_date('"+daInicioDoc+"'," +
				"'"+CLPConstantes.DATE_PATTERN+"') and clpmid.da_fecha_incidencia  <= to_date('"+daFinDoc+"','"+CLPConstantes.DATE_PATTERN+"'))");
			}
			
			if (StringUtils.isNotBlank(coTipoIncidenciaPuntos) && !"-1".equals(coTipoIncidenciaPuntos)){
				query.append(" and clpmid.co_tipo_incidencia_puntos = ").append(coTipoIncidenciaPuntos);
			}		
			
			if (coTipo> 0){
				query.append(" and clpmid.co_tipo = ").append(coTipo);
			}				
			
			query.append(" and (clpmid.st_incidencia_puntos = ").append("'"+CLPConstantes.ST_VERDADERO+"'").append(")");
			
			System.out.println("*** IncidenciaPuntosDaoImpl.busquedaIncidencia() --> "+query.toString());
			return findListOfBeans(query.toString(), null, BNIncidenciaPuntos.class);

	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Map guardarIncidencia(BNIncidenciaPuntos bnincidencia) {
		
		Map map = new HashMap();
		//se inicia la transaccion para guardar todo el bloque
	
		try{
			
			Long coTipo 					= bnincidencia.getCoTipo();
			BigDecimal vaPuntos 	  		= bnincidencia.getVaPuntos();
			String deSustentacion 			= bnincidencia.getDeSustentacion();
			Long coClientePersona 			= bnincidencia.getCoClientePersona();
			String codCodigoTarjetaPersona 	= bnincidencia.getCoTarjetaPersona();			
			Long coTipoIncidenciaPuntos 	= bnincidencia.getCoTipoIncidenciaPuntos();
			
			BNClientesPersona beancliente = obtenerDatosClientePorTarjeta(codCodigoTarjetaPersona);
			if(StringUtils.isBlank(beancliente.getDeNombre())){
				map.put("msg", "error");
				map.put("detalle", "penalizacionbonificacionform.error.codigotarjeta.invalido");
				return (HashMap)map;
			}
			
			StringBuffer query = new StringBuffer();
			query.append(" select * ");
			query.append(" from clpm_puntos_periodo_cliente cptos ");
			query.append(" inner join clpr_periodo_acumulacion cpa ");
			query.append(" 		on  cpa.id =cptos.co_periodo_acumulacion ");
			query.append(" where co_cliente_persona = ").append(beancliente.getCoClientePersona());
			query.append(" 		and cpa.da_fecha_inicio<=sysdate ");
			query.append(" 		and cpa.da_fecha_vencimiento_puntos>=sysdate ");
			query.append(" 		and cpa.da_fecha_inicio<=cptos.da_fecha_creacion  ");
			query.append(" 		and cpa.da_fecha_vencimiento_puntos>= cptos.da_fecha_creacion ");
			System.out.println("lista de usuario puntos"+query.toString());
			List listClientePuntos = jdbcTemplate.queryForList(query.toString());
			
			ClpmIncidenciaPuntos clpmincidencia = new ClpmIncidenciaPuntos();
			ClpbTipoIncidenciaPuntos clpbtipoincidencia = new ClpbTipoIncidenciaPuntos();
			clpbtipoincidencia.setId(coTipoIncidenciaPuntos);
			ClpbClientePersona clpbclientepersona = new ClpbClientePersona();
			clpbclientepersona.setId(coClientePersona);
			
			clpmincidencia.setCoCodigoTarjetaPersona(codCodigoTarjetaPersona);
			clpmincidencia.setClpbClientePersona(clpbclientepersona);
			clpmincidencia.setDaFechaIncidencia(CalendarUtil.stringToCalendar(CLPConstantes.DATE_PATTERN, bnincidencia.getDaFechaIncidencia()));
			clpmincidencia.setCoTipo(coTipo);
			clpmincidencia.setClpbTipoIncidenciaPuntos(clpbtipoincidencia);
			clpmincidencia.setVaPuntos(vaPuntos);
			clpmincidencia.setDeSustentacion(deSustentacion);
			clpmincidencia.setStIncidenciaPuntos(Boolean.TRUE);
			clpmincidencia.setCoUsuarioCreador(getUsuarioLogueado().getUsername());
			clpmincidencia.setDaFechaCreacion(Calendar.getInstance());
			
			
			//UPDATES PUNTOS DEL CLIENTE
			String[] arrayStr = new String[1];
			long vaPuntosCliente = vaPuntos.longValue();
			if(listClientePuntos.isEmpty()){
				
				query = new StringBuffer();
				query.append(" insert into clpm_puntos_periodo_cliente ");
				query.append(" (id,co_cliente_persona,va_puntos_actuales,va_puntos_totales");
				query.append("	st_puntos_periodo_cliente,co_usuario_creador,da_fecha_creacion) ");
				query.append(" values (");
				query.append(" seq_cliente_puntos.nextval,"+beancliente.getCoClientePersona()+",");
				query.append(" "+vaPuntosCliente+","+vaPuntosCliente+",'"+CLPConstantes.ST_VERDADERO+"','").append(getUsuarioLogueado().getUsername()).append("',");
				query.append(" sysdate)");
				System.out.println("lista de usuario puntos/insert"+query.toString());
				arrayStr[0] = query.toString();
				
			}else{
				
				query = new StringBuffer();
				query.append(" update clpm_puntos_periodo_cliente ");
				query.append(" set ");
				query.append(" 	va_puntos_totales = va_puntos_totales + ").append(vaPuntosCliente).append(",");
				query.append(" 	va_puntos_actuales  = decode(va_puntos_actuales,null,"+vaPuntosCliente+",va_puntos_actuales + "+vaPuntosCliente+"),");
				query.append(" 	co_usuario_modificador  = '").append(getUsuarioLogueado().getUsername()).append("' ,");
				query.append("	da_fecha_modificacion   = sysdate ");
				query.append(" where co_cliente_persona = ").append(beancliente.getCoClientePersona());
				System.out.println("lista de usuario puntos/udpates"+query.toString());
				arrayStr[0] = query.toString();
			}		
			
			getHibernateTemplate().saveOrUpdate(clpmincidencia);
			getHibernateTemplate().flush();
	
			jdbcTemplate.batchUpdate(arrayStr);
			
			for (int i = 0; i < arrayStr.length; i++) {
				System.out.println(i+"* update detalle guardarIncidencia(): "+arrayStr[i]);
			}
			
			map.put("msg", "success");
			map.put("id" , clpmincidencia.getId());
			
		}catch(Exception e){
			
			getHibernateTemplate().clear();		
			map.put("msg", "error");
			map.put("detalle", e.getMessage());
			log.info(e.getMessage());
			System.out.println(e.getMessage());
		}
		
		return (HashMap)map;
	}


	@SuppressWarnings("unchecked")
	public BNIncidenciaPuntos obtenerIncidencia(Long id) {
		StringBuffer query = new StringBuffer();
		query.append(" SELECT clpmid.id                                                  AS id                    , ");
		query.append("   clpmid.co_codigo_tarjeta_persona                                 AS coTarjetaPersona      ,");
		query.append("   clpmid.co_cliente_persona                                        AS coClientePersona      ,");
		query.append(" 		  clpmid.co_tipo                              AS coTipo,");
		query.append(" 		  clpmid.co_tipo_incidencia_puntos                                 AS coTipoIncidenciaPuntos,");
		query.append(" 		   to_char(clpmid.da_fecha_creacion,'"+CLPConstantes.DATE_PATTERN+"')                                         AS daFechaCreacion     ,");
		query.append(" 		   to_char(clpmid.da_fecha_incidencia,'"+CLPConstantes.DATE_PATTERN+"')                                         AS daFechaIncidencia     ,");
		query.append(" 		  clpbti.de_tipo_incidencia_puntos AS daTipoIncidenciaPuntos, ");
		query.append(" 		  clpmid.de_sustentacion                                             AS deSustentacion        ,");
		query.append(" 		  clpmid.va_puntos                                                 AS vaPuntos              ,");
		query.append(" 		    clpbcp.de_nombre||' '|| clpbcp.de_ape_paterno||' '||clpbcp.de_ape_materno AS deClientePersona");
		query.append(" 		   FROM clpm_incidencia_puntos clpmid ");
		query.append(" 		JOIN clpb_tipo_incidencia_puntos clpbti ");
		query.append(" 		     ON clpbti.id = clpmid.co_tipo_incidencia_puntos ");
		query.append(" 		JOIN clpb_cliente_persona clpbcp ");
		query.append(" 		     ON clpbcp.id = clpmid.co_cliente_persona ");
		query.append(" 		     WHERE 1= 1 ");
			query.append(" and (clpmid.st_incidencia_puntos = ").append("'"+CLPConstantes.ST_VERDADERO+"'").append(")");
			query.append(" and (clpmid.id   = ").append(id).append(")");
			
			System.out.println("*** IncidenciaPuntosDaoImpl.obtenerIncidenciaaaaaaaaaaaaa() --> "+query.toString());
			
			List<BNIncidenciaPuntos> listIncidencia = findListOfBeans(query.toString(), null, BNIncidenciaPuntos.class);			
			
			if(!listIncidencia.isEmpty()){
				return (BNIncidenciaPuntos)listIncidencia.get(0);	
			}
			
			return new BNIncidenciaPuntos();			

	}	
	

	@SuppressWarnings("rawtypes")
	public BNClientesPersona obtenerDatosClientePorTarjeta(String codeTarjeta) {

		StringBuffer query = new StringBuffer();
		query.append(" select ");
		query.append(" cp.id, ");
		query.append(" cp.de_nombre||' '|| cp.de_ape_paterno||' '||cp.de_ape_materno as deNombre, ");
		query.append(" cptos.va_puntos_actuales as dePuntosAcumulados,  ");
		query.append(" tp.co_cliente_persona as coClientePersona  ");
		query.append(" from clpb_tarjeta_persona tp ");
		query.append(" inner join clpb_cliente_persona cp ");
		query.append(" 		on cp.id = tp.co_cliente_persona ");
		query.append(" left join clpm_puntos_periodo_cliente cptos ");
		query.append(" 		on cptos.co_cliente_persona = tp.co_cliente_persona ");
		query.append(" inner join clpr_periodo_acumulacion cpa ");
		query.append(" 		on  cpa.id =cptos.co_periodo_acumulacion ");
		query.append(" where 1 = 1 ");
		query.append(" 		and trim(tp.co_codigo_tarjeta_persona) = '").append(codeTarjeta.trim()).append("'");
		query.append(" 		and cpa.da_fecha_inicio<=sysdate ");
		query.append(" 		and cpa.da_fecha_vencimiento_puntos>=sysdate ");
		query.append(" 		and cpa.da_fecha_inicio<=cptos.da_fecha_creacion  ");
		query.append(" 		and cpa.da_fecha_vencimiento_puntos>= cptos.da_fecha_creacion ");
		query.append(" 		and cp.st_cliente_persona = '").append(CLPConstantes.ST_VERDADERO).append("'");
		query.append(" 		and tp.st_tarjeta_persona = '").append(CLPConstantes.ST_VERDADERO).append("'");
		
		System.out.println(" ** obtenerDatosClientePorTarjeta()--> "+query.toString());
		List list = findListOfBeans(query.toString(), null, BNClientesPersona.class);
		if(list != null && !list.isEmpty()){
			return (BNClientesPersona)list.get(0);
		}
		
		return new BNClientesPersona();
	}

	@SuppressWarnings("unchecked")
	public List<BNIncidenciaPuntos> listaIncidencias() {
		String strFechaDoc = "to_char(cast(" +
		"clpmid.da_fecha_incidencia as date),  " +
		"'"+CLPConstantes.DATE_PATTERN+"')";

		String strFechaRegistro = "to_char(cast(" +
		"clpmid.da_fecha_creacion as date),  " +
		"'"+CLPConstantes.DATE_PATTERN+"')";		
		
		StringBuffer query = new StringBuffer();
			query.append(" select * from (");
			query.append(" SELECT clpmid.id                                                  AS id                    , ");
			query.append("   clpmid.co_codigo_tarjeta_persona                                 AS coTarjetaPersona      ,");
			query.append("   clpmid.co_cliente_persona                                        AS coClientePersona      ,");
			query.append(" 		  clpmid.co_tipo                               AS coTipo,");
			query.append(" 		  clpmid.co_tipo_incidencia_puntos                                 AS coTipoIncidenciaPuntos,");
			query.append(" 		  clpbti.de_tipo_incidencia_puntos AS daTipoIncidenciaPuntos, ");
			query.append(" 		"+strFechaDoc+" as daFechaIncidencia ,");
			query.append(" 		"+strFechaRegistro+" as daFechaCreacion ,");
			query.append(" 		  clpmid.de_sustentacion                                             AS deSustentacion        ,");
			query.append(" 		  clpmid.va_puntos                                                 AS vaPuntos              ,");
			query.append(" 		   clpbcp.de_nombre||' '|| clpbcp.de_ape_paterno||' '||clpbcp.de_ape_materno AS deClientePersona");
			query.append(" 		   FROM clpm_incidencia_puntos clpmid ");
			query.append(" 		JOIN clpb_tipo_incidencia_puntos clpbti ");
			query.append(" 		     ON clpbti.id = clpmid.co_tipo_incidencia_puntos ");
			query.append(" 		JOIN clpb_cliente_persona clpbcp ");
			query.append(" 		     ON clpbcp.id = clpmid.co_cliente_persona ");
			query.append(" 		     WHERE 1= 1 ");					
			query.append(" and (clpmid.st_incidencia_puntos = ").append("'"+CLPConstantes.ST_VERDADERO+"'").append(")");

			
			query.append(" order by clpmid.id desc ");
			query.append(" ) where rownum <= ").append(CLPConstantes.MAXIMO_RESULTADO_INICIAL);
		
		System.out.println("*** IncidenciaPuntosDaoImpl.listaIncidencias() --> "+query.toString());
		return findListOfBeans(query.toString(), null, BNIncidenciaPuntos.class);
	}
	
	
	
	public String verificarPeriodoAcumulacion(String daFechaIncidencia){
		
		int resultado=0;
		StringBuffer query= new StringBuffer();
		
		query.append(" select ");
		query.append(" count(id) from clpr_periodo_acumulacion "); 
		query.append(" where da_fecha_inicio <= to_date('"+daFechaIncidencia+"','dd/MM/yyyy') ");
		query.append("  and da_fecha_fin >=to_date('"+daFechaIncidencia+"','dd/MM/yyyy') ");
		
		System.out.println(query.toString());
		resultado=jdbcTemplate.queryForInt(query.toString());
		if(resultado>=1){
			return CLPConstantes.SUCCESS;
		}
		
		return CLPConstantes.ERROR;
	}
	
	
	
}
